package com.edu.base.common.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SimpleTimeZone;
import java.util.UUID;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.google.common.collect.Maps;
import com.ruoyi.common.utils.UUIDUtils;
import com.thoughtworks.xstream.core.util.Base64Encoder;

public class AliOssVideoUtils {

    /**
     *@Description 获取签名结果
     *@Param [accessKeyId, accessKeySecret, videoId]
     *@Return java.lang.String
     *@Author Wzq
     *@Date 2020/1/14
     *@Time 19:30
     */
    public static String getVideoInfo(String accessKeyId,String accessKeySecret,String videoId) throws IOException {
    	accessKeyId="LTAI4FiY1zoVAeFKspnJuLeH";
    	accessKeySecret="9K889H4GdLYclI78WFfGp0CkRacAUZ";
        String timestamp = generateTimestamp();
        String signatureNonce = generateRandom();
        //1.1. 构造规范化的请求字符串
        Map<String, String> privateParams = Maps.newLinkedHashMap();
        privateParams.put("Action","GetVideoInfo");
        privateParams.put("VideoId", videoId);
        Map<String, String> publicParams = Maps.newLinkedHashMap();
        publicParams.put("Timestamp",timestamp);
        publicParams.put("Format","JSON");
        publicParams.put("AccessKeyId",accessKeyId);
        publicParams.put("SignatureMethod", "HMAC-SHA1");
        publicParams.put("SignatureNonce",signatureNonce);
        publicParams.put("Version", "2017-03-21");
        publicParams.put("SignatureVersion","1.0");

        List<String> allParams = getAllParams(publicParams, privateParams);

        String canonicalizedQueryString = getCQS(allParams);

        //1.2. 构造待签名的字符串
        /*构造待签名的字符串*/
        String StringToSign = "GET" + "&" + percentEncode("/") + "&" +percentEncode(canonicalizedQueryString);

        //1.3. 计算待签名字符串的HMAC值
        byte[] bytes = hmacSHA1Signature(accessKeySecret, StringToSign);

        //1.4. 编码得到最终签名值
        //按照 Base64 编码规则将1.3中计算得到的HMAC值编码成字符串，得到最终签名值（Signature）。
        String signature =newStringByBase64(bytes);
//        log.info("-------------"+signature);
        Map<String,String> videoInfoMap = Maps.newLinkedHashMap();
        videoInfoMap.put("Action","GetVideoInfo");
        videoInfoMap.put("VideoId", videoId);
        videoInfoMap.put("Format","JSON");
        videoInfoMap.put("AccessKeyId",accessKeyId);
        videoInfoMap.put("Signature",signature);
        videoInfoMap.put("SignatureMethod","HMAC-SHA1");
        videoInfoMap.put("SignatureVersion","1.0");
        videoInfoMap.put("SignatureNonce",signatureNonce);
        videoInfoMap.put("Timestamp", timestamp);
        videoInfoMap.put("Version","2017-03-21");
        String resultStr = null;
		//调用http get请求
       // String resultStr = HttpUtil.post("http://paekdusan.oss-cn-beijing.aliyuncs.com", videoInfoMap);
//        log.info(s);
        return resultStr;
    }
    /*对所有参数名称和参数值做URL编码*/
    public static List<String> getAllParams(Map<String, String> publicParams, Map<String, String> privateParams) {
        List<String> encodeParams = new ArrayList<String>();
        if (publicParams != null) {
            for (String key : publicParams.keySet()) {
                String value = publicParams.get(key);
                //将参数和值都urlEncode一下。
                String encodeKey = percentEncode(key);
                String encodeVal = percentEncode(value);
                encodeParams.add(encodeKey + "=" + encodeVal);
            }
        }
        if (privateParams != null) {
            for (String key : privateParams.keySet()) {
                String value = privateParams.get(key);
                //将参数和值都urlEncode一下。
                String encodeKey = percentEncode(key);
                String encodeVal = percentEncode(value);
                encodeParams.add(encodeKey + "=" + encodeVal);
            }
        }
        return encodeParams;
    }
    /*获取 CanonicalizedQueryString*/
    public static String getCQS(List<String> allParams) {
        ParamsComparator paramsComparator = new ParamsComparator();
        Collections.sort(allParams, paramsComparator);
        String cqString = "";
        for (int i = 0; i < allParams.size(); i++) {
            cqString += allParams.get(i);
            if (i != allParams.size() - 1) {
                cqString += "&";
            }
        }
        return cqString;
    }
    /*字符串参数比较器，按字母序升序*/
    public static class ParamsComparator implements Comparator<String> {
        @Override
        public int compare(String lhs, String rhs) {
            return lhs.compareTo(rhs);
        }
    }

    public static byte[] hmacSHA1Signature(String accessKeySecret, String stringToSign) {
        try {
            String key = accessKeySecret + "&";
            try {
                SecretKeySpec signKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
                Mac mac = Mac.getInstance("HmacSHA1");
                mac.init(signKey);
                return mac.doFinal(stringToSign.getBytes());
            } catch (Exception e) {
                throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
            }
        } catch (SignatureException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String newStringByBase64(byte[] bytes)
            throws UnsupportedEncodingException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        return new String(new Base64Encoder().encode(bytes));
    }

    /*特殊字符替换为转义字符*/
    public static String percentEncode(String value) {
        try {
            String urlEncodeOrignStr = URLEncoder.encode(value, "UTF-8");
            String plusReplaced = urlEncodeOrignStr.replace("+", "%20");
            String starReplaced = plusReplaced.replace("*", "%2A");
            String waveReplaced = starReplaced.replace("%7E", "~");
            return waveReplaced;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return value;
    }

    /*生成当前UTC时间戳Time*/
    public static String generateTimestamp() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df.format(date);
    }

    /*生成随机数SignatureNonce*/
    public static String generateRandom() {
        String signatureNonce = UUIDUtils.getUUID();
        return signatureNonce;
    }
}
